<template>
  <div
    class="login-container bg-[url('@/assets/images/login-background-light.jpg')] dark:bg-[url('@/assets/images/login-background-dark.jpg')]"
  >
    <!-- 登录页头部 -->
    <div class="absolute top-0 flex justify-end w-full p-15px">
      <div class="flex items-center">
        <el-switch
          v-model="isDark"
          inline-prompt
          active-icon="Moon"
          inactive-icon="Sunny"
          @change="toggleTheme"
        />
        <lang-select class="ml-2 cursor-pointer" />
      </div>
    </div>

    <!-- 登录页内容 style="min-width: 600px" -->
    <div
      class="login-card bg-white shadow dark:bg-transparent dark:shadow-[var(--el-box-shadow)]"
    >
      <div
        class="login-card-logo bg-transparent bg-gradient-to-br from-[#3a485a] to-[#607089]"
        style="flex-shrink: 0"
      >
        <el-image :src="publicInfo.public_logo" style="width: 100px" />
      </div>
      <div class="login-card-form" style="flex-shrink: 0">
        <el-form ref="loginFormRef" :model="loginData" :rules="loginRules">
          <div class="login-card-form-header">
            <h2 class="text-[#303133]">
              {{ publicInfo.public_title }}
            </h2>
            <div class="text-14px font-500 text-[#606266]">
              {{ publicInfo.public_subtitle }}
            </div>
          </div>

          <!-- 用户名 -->
          <el-form-item prop="username">
            <div class="flex items-center w-full">
              <el-input
                ref="username"
                v-model="loginData.username"
                :placeholder="$p('menu.auth.login.username', '用户名')"
                name="username"
                clearable
                class="h-[48px]"
                size="large"
                :prefix-icon="User"
              />
            </div>
          </el-form-item>

          <!-- 密码 -->
          <el-tooltip
            :visible="isCapslock"
            :content="$t('menu.auth.login.caps_lock')"
            placement="right"
          >
            <el-form-item prop="password">
              <div class="flex items-center w-full">
                <el-input
                  v-model="loginData.password"
                  :placeholder="$p('menu.auth.login.password', '密码')"
                  type="password"
                  name="password"
                  show-password
                  clearable
                  class="h-[48px]"
                  size="large"
                  :prefix-icon="Lock"
                  @keyup="checkCapslock"
                  @keyup.enter="handleLoginSubmit"
                />
              </div>
            </el-form-item>
          </el-tooltip>

          <!-- 验证码 -->
          <el-form-item prop="captchaCode" v-if="captchaShow">
            <div class="flex items-center w-full">
              <el-input
                v-model="loginData.captchaCode"
                auto-complete="off"
                :placeholder="$p('menu.auth.login.captcha_code', '验证码')"
                @keyup.enter="handleLoginSubmit"
                class="h-[48px]"
                size="large"
                :prefix-icon="Bell"
              >
                <template #suffix>
                  <el-image
                    :src="captchaBase64"
                    class="login-card-form-captcha"
                    @click="getCaptcha"
                  />
                </template>
              </el-input>
            </div>
          </el-form-item>

          <div class="flex justify-between items-center w-full py-1">
            <el-checkbox v-model="loginData.rememberMe">
              {{ $t('menu.auth.login.remember_me') }}
            </el-checkbox>
          </div>

          <!-- 登录按钮 -->
          <el-button
            :loading="loading"
            type="primary"
            size="large"
            class="w-full"
            @click.prevent="handleLoginSubmit"
          >
            {{ $t('menu.auth.login.login') }}
          </el-button>
          <div class="flex flex-col justify-between items-center w-full py-1">
            <div class="text-center text-12px font-100 text-[#303133] pt-10px">
              {{ publicInfo.public_version }}
            </div>
          </div>
        </el-form>
      </div>
    </div>

    <!-- 登录页底部 -->
    <div class="absolute bottom-0 w-full text-center">
      <el-text size="small">
        {{ publicInfo.public_copyright }}
        <a href="http://beian.miit.gov.cn/" target="_blank">
          {{ publicInfo.public_beian }}
        </a>
      </el-text>
    </div>
  </div>
</template>

<script setup>
import { useRoute, useRouter } from 'vue-router';
import { ref, computed, onMounted } from 'vue';
import { cookie } from 'xe-utils';
import { User, Lock, Bell } from '@element-plus/icons-vue';
import { smartTranslate as $t, transPlaceholder as $p } from '@/lang';
import LoginAPI from '@/api/admin/login';
import { ThemeEnum } from '@/enums';
import { useSettingsStore, useUserStore, usePublicInfoStore } from '@/store';

const userStore = useUserStore();
const settingsStore = useSettingsStore();
const { publicInfo, loadPublicInfo } = usePublicInfoStore();

const router = useRouter();
const route = useRoute();
const loginFormRef = ref();

const isDark = ref(settingsStore.theme === ThemeEnum.DARK);
const loading = ref(false); // 按钮 loading 状态
const isCapslock = ref(false); // 是否大写锁定
const captchaBase64 = ref(); // 验证码图片Base64字符串
const captchaShow = ref(false);

const loginData = ref({
  username: '',
  password: '',
  captchaKey: '',
  captchaCode: '',
  rememberMe: null,
});

const loginRules = computed(() => {
  const requiredMessage = (field) =>
    $t('common.message.validate.required', '{field}不能为空', { field });
  const minLengthMessage = (field, min) =>
    $t('common.message.validate.min', '{field}不能少于{min}个字符！', {
      field,
      min,
    });

  return {
    username: [
      {
        required: true,
        trigger: 'blur',
        message: requiredMessage($t('menu.auth.login.username', '用户名')),
      },
    ],
    password: [
      {
        required: true,
        trigger: 'blur',
        message: requiredMessage($t('menu.auth.login.password', '密码')),
      },
      {
        min: 6,
        message: minLengthMessage($t('menu.auth.login.password', '密码'), 6),
        trigger: 'blur',
      },
    ],
    captchaCode: [
      {
        required: true,
        trigger: 'blur',
        message: requiredMessage($t('menu.auth.login.captcha_code', '验证码')),
      },
    ],
  };
});

// 获取验证码
function getCaptcha() {
  LoginAPI.getCaptcha().then(({ data }) => {
    loginData.value.captchaKey = data.captchaKey;
    captchaBase64.value = data.captchaBase64;
    captchaShow.value = data.captchaShow;
  });
}

// 设置登录凭证 注意不应该前端解密密码。
const setLoginCredentials = () => {
  const username = cookie('username');
  const password = cookie('password');
  const rememberMe = cookie('rememberMe');

  loginData.value.username = username || '';
  loginData.value.password = password ? atob(password) : '';
  loginData.value.rememberMe = rememberMe === 'true';
};

// 保存登录凭证
const saveLoginCredentials = () => {
  cookie('username', loginData.value.username, { expires: 15 });
  cookie('password', btoa(loginData.value.password), { expires: 15 });
  cookie('rememberMe', loginData.value.rememberMe, { expires: 15 });
};

// 清除登录凭证
const clearLoginCredentials = () => {
  cookie.remove('username');
  cookie.remove('password');
  cookie.remove('rememberMe');
};

// 登录
async function handleLoginSubmit() {
  loginFormRef.value.validate(async (valid) => {
    if (valid) {
      loading.value = true;
      try {
        if (loginData.value.rememberMe) {
          saveLoginCredentials();
        } else {
          clearLoginCredentials();
        }
        await userStore.login(loginData.value);
        const { path, queryParams } = parseRedirect();
        router.push({ path, query: queryParams });
      } catch (error) {
        getCaptcha();
      } finally {
        loading.value = false;
      }
    }
  });
}

/**
 * 解析 redirect 字符串 为 path 和  queryParams
 *
 * @returns { path: string, queryParams: Record<string, string> } 解析后的 path 和 queryParams
 */
function parseRedirect() {
  const query = route.query;
  const redirect = query.redirect || '/';

  const url = new URL(redirect, window.location.origin);
  const path = url.pathname;
  const queryParams = {};

  url.searchParams.forEach((value, key) => {
    queryParams[key] = value;
  });

  return { path, queryParams };
}

// 主题切换
const toggleTheme = () => {
  const newTheme =
    settingsStore.theme === ThemeEnum.DARK ? ThemeEnum.LIGHT : ThemeEnum.DARK;
  settingsStore.changeTheme(newTheme);
};

// 检查输入大小写
function checkCapslock(event) {
  // 防止浏览器密码自动填充时报错
  if (event instanceof KeyboardEvent) {
    isCapslock.value = event.getModifierState('CapsLock');
  }
}

onMounted(() => {
  getCaptcha();
  loadPublicInfo();
  // 优化条件判断,直接检查 rememberMe cookie 的值
  if (cookie('rememberMe') === 'true') {
    setLoginCredentials();
  }
});

defineOptions({
  name: 'BaseLogin',
  inheritAttrs: false,
});
</script>

<style scoped>
/* 统一处理 Element Plus 表单项和输入框的样式 */
:deep(.el-form-item) {
  background: var(--el-input-bg-color);
  border: 1px solid var(--el-border-color);
  border-radius: 5px;
}

:deep(.el-input__wrapper) {
  padding: 0;
  background-color: transparent;
  box-shadow: none;
}

:deep(.el-input__prefix-inner) {
  margin-left: 5px;
}

:deep(.el-input__wrapper.is-focus),
:deep(.el-input__wrapper:hover) {
  box-shadow: none !important;
}

:deep(input:-webkit-autofill) {
  /* 通过延时渲染背景色变相去除背景颜色 */
  transition: background-color 1000s ease-in-out 0s;
}

.login-container {
  @apply flex 
  items-center 
  justify-center 
  w-full h-full 
  overflow-y-auto 
  bg-no-repeat 
  bg-center 
  bg-right;
}

.login-card {
  @apply flex 
  overflow-x-auto 
  overflow-y-hidden  
  rounded-5px
  h-[500px] 
  lt-lg:flex-col 
  lt-lg:max-w-full 
  lt-lg:px-30px 
  lt-lg:rounded-0 
  lt-lg:shadow-none;
}
.login-card-logo {
  @apply flex 
  flex-col 
  w-480px 
  items-center 
  justify-center 
  lt-lg:hidden;
}
.login-card-form {
  @apply flex 
  flex-col 
  justify-center 
  w-480px 
  px-30px 
  py-30px 
  lt-lg:w-full 
  lt-lg:px-20px 
  lt-lg:py-20px;
}
.login-card-form-header {
  @apply flex 
  flex-col 
  items-center 
  justify-center 
  pb-20px 
  text-center;
}
.login-card-form-captcha {
  @apply h-46px 
  cursor-pointer 
  rounded-tr-6px 
  rounded-br-6px 
  mr-1;
}
</style>
